package com.yzl.frelink.service.matlab;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.yzl.frelink.entities.chart.StateTreeNode;
import com.yzl.frelink.entities.component.Chart;
import com.yzl.frelink.entities.component.Component;
import com.yzl.frelink.entities.model.Model;

@Service
public class StateCompiler {
    @Value("${frelink.stateCode}")
    private String stateCode;

    public String compileStates(Model model) {
        int chartCount = 0;
        List<String> chartStates = new ArrayList<>();
        for (Chart chart : model.getCharts()) {
            chartCount++;
            StringBuilder sb = new StringBuilder();
            sb.append("labelStrings = [").append(compileLabels(chart)).append("];\n");
            sb.append("positions = [").append(compilePositions(chart)).append("];\n");
            sb.append("types = [").append(compileTypes(chart)).append("];\n");
            sb.append("states").append(chartCount).append(" = setStates(charts(").append(chartCount).append(")");
            sb.append(", labelStrings, positions, types);\n");
            chartStates.add(sb.toString());
//             chartStates.add("""
// labelStrings = [%s];
// positions = [%s];
// types = [%s];
// states%d = setStates(charts(%d), labelStrings, positions, types);
// """.formatted(compileLabels(chart), compilePositions(chart), compileTypes(chart), chartCount, chartCount));
        }
        return stateCode + "\n" + String.join("\n", chartStates);
//         return """
// %% create states in a vertical layout
// %% stateflow will deprate the 'initial state'
// function state = addState(ch, labelString, position, type)
//   if type == 2
//     state = Stateflow.Junction(ch);
//     state.Position.Center = position(1, 1:2);
//   else  
//     state = Stateflow.State(ch);
//     state.LabelString = labelString;
//     state.Position = position;
//     if type == 3
//       state.Decomposition = 'PARALLEL_AND';
//     end
//   end
// end

// function states = setStates(chart, labelStrings, positions, isParas)
//     mn = size(labelStrings);
//     nowSize = mn(2);
//     for i = 1 : nowSize
//         states(i) = addState(chart, labelStrings(i), positions(i, :), isParas(i));
//     end
// end

// %s
// """.formatted(String.join("\n", chartStates));
    }

    private String compileLabels(Chart chart) {
        List<String> label = new ArrayList<>();
        for (String stateName : chart.getStatesCompilingOrder()) {
            StateTreeNode state = chart.getState(stateName);
            if (state.getType() != 1) {
                label.add(state.getMatlabLabel());
            }
        }
        return String.join(", ", label);
    }

    private String compilePositions(Chart chart) {
        List<String> position = new ArrayList<>();
        for (String stateName : chart.getStatesCompilingOrder()) {
            StateTreeNode state = chart.getState(stateName);
            if (state.getType() != 1) {
                String stringWithBrackets = Arrays.toString(state.getPosition());
                stringWithBrackets = stringWithBrackets.substring(1, stringWithBrackets.length() - 1);
                position.add(stringWithBrackets);
            }
        }
        return String.join("; ", position);
    }

    private String compileTypes(Chart chart) {
        List<String> type = new ArrayList<>();
        for (String stateName : chart.getStatesCompilingOrder()) {
            StateTreeNode state = chart.getState(stateName);
            if (state.getType() != 1) {
                type.add(String.valueOf(state.getType()));
            }
        }
        return String.join(", ", type);
    }
}
